﻿/* CloakingCalc.cs
 * Author: Richard Broker
 * 
 *  This file is part of Tame.
 *
 *  Tame is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  Tame is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with Tame. If not, see <http://www.gnu.org/licenses/>.
 *
 * Special thanks to: http://forum.pardus.at/archive/index.php?showtopic=47348&hl=cloak
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.ComponentModel;

namespace Tame
{
    class CloakingCalc
    {

        int cloakingDevice;
        string shipSelectBox;
        double inv_fieldrad;
        public CloakingCalc(double INV_FIELDRAD, string SHIP_NAME, int CLOAK_DEVICE)
        {
            cloakingDevice = CLOAK_DEVICE;
            shipSelectBox = SHIP_NAME;
            inv_fieldrad = INV_FIELDRAD;
        }

 
        public double CalculateCloakingSkillGain(bool cloakFailed, double cloakSkill)
        {
            double skill = 2.5 / Math.Pow(Math.Floor(cloakSkill), 2);

            if (cloakFailed == true)
            {
                skill = skill / 10;
            }

            return skill;
        }

        public int determineDaysOfCloakTrainingLeft(double startSkill, double endSkill, int maxAP)
        {
            double currSkill = startSkill;
            double chanceToSucceed = 0 ;
            double chanceToFail = 0;
            double SuccessGain =0;
            double FailGain =0;
            double avgGain;
            int cloaks =0;
            int apRequired = 0;
            int days = 0;

            for (; currSkill < endSkill; cloaks++)
            {
                if ((startSkill + 500) < endSkill)
                {
                    MessageBox.Show("This could take a while - to avoid the program getting stuck and locking up, I'm going to stop looking. Your skilling time remaining is likely in the order of decades, so you may want to get moving!", "Uh...");
                    break;
                }
                // See gain
               SuccessGain = CalculateCloakingSkillGain(false, currSkill);
               FailGain= CalculateCloakingSkillGain(true, currSkill);

                // See chance of failure.
               chanceToSucceed = calculateCloakingChance(currSkill);

               if (chanceToSucceed == -1)
               {
                   return -1;
               }
               chanceToFail = 1 - chanceToSucceed;

               avgGain = ((chanceToSucceed * SuccessGain) + (chanceToFail * FailGain));

               currSkill += avgGain;              

            }
            
            apRequired = cloaks * 100;
            days = apRequired / maxAP;

            return days; 
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="inv_fieldrad"></param>
        /// <param name="shipSelectBox"></param>
        /// <param name="skill"></param>
        /// <param name="cloakingDevice">0 is none, 1 is normal, 2 is advanced</param>
        /// <returns></returns>
        public double calculateCloakingChance(double skill)
        {
            // Calling event handler should:
            // Make it so user doesn't need to refresh before calculating.
            //refreshPilotTabSkills();

            int modeSize = 3;
            Ship playerShip = new Ship();
            double shipSize = (double)playerShip.GetShipData(ref modeSize, shipSelectBox);
            bool error = false;

            if ((shipSize == 0) && (inv_fieldrad > 0))
            {
                MessageBox.Show("You currently don't have a ship selected on the \"Designer\" tab. Can't do anything until this is corrected", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                error = true;
            }
            if (error != true)
            {
                if ((shipSize == 0) && (inv_fieldrad == 0))
                {
                    MessageBox.Show("You currently don't have a ship selected on the \"Designer\" tab, you also don't have a tile-type selected. Can't do anything until both these issues are corrected.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    error = true;
                }
            }
            if (error != true)
            {
                if ((shipSize > 0) && (inv_fieldrad == 0))
                {
                    MessageBox.Show("You currently don't have a tile type selected from the drop-down menu. Can't do anything until this is corrected", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    error = true;
                }
            }

            if (error != true)
            {
                try
                {
                    double cloakskill = skill;
                    double cloakingchance;
                    double cloakingchanceWithCloaker = 0;
                    cloakingchance = ((shipSize * inv_fieldrad) / (cloakskill * 10));
                    cloakingchance = 1 - cloakingchance;

                    if (cloakingchance < 0)
                    {
                        cloakingchance = 0;
                    }

                    // If cloaker is installed:
                    if (cloakingDevice == 1)
                    {
                        cloakingchanceWithCloaker = cloakingchance + 0.25;
                    }
                    if (cloakingDevice == 2)
                    {
                        cloakingchanceWithCloaker = cloakingchance + 0.4;
                    }

                    if (cloakingchanceWithCloaker > 1)
                    {
                        cloakingchanceWithCloaker = 1;
                    }
                    if (cloakingchance > 1)
                    {
                        cloakingchance = 1;
                    }

                    return cloakingchance;
                }
                catch (FormatException)
                {
                    MessageBox.Show("Cloaking Skill must be entered on the \"Pilot\" tab as a number. No punctuation, no letters no funny business - just numbers.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return -1;
                }
            }
            return -1;
        }
    }


}
